package logic

import (
	"context"
	"time"

	"go-weixin/app/usercenter/rpc/internal/domain"
	"go-weixin/app/usercenter/rpc/internal/svc"
	"go-weixin/app/usercenter/rpc/pb/proto/usercenter"
	"go-weixin/common/utils"

	mapset "github.com/deckarep/golang-set/v2"
	"github.com/zeromicro/go-zero/core/logx"
)

type UserLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
	userDomain *domain.UserDomain
	ut         utils.Utils
}

func NewUserLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserLogic {
	return &UserLogic{
		ctx:        ctx,
		svcCtx:     svcCtx,
		Logger:     logx.WithContext(ctx),
		userDomain: domain.NewUserDomain(*svcCtx.ChenDb, *svcCtx.ChenCache),
	}
}

// 定义一个 SayHello 一元 rpc 方法，请求体和响应体必填。
func (l *UserLogic) Register(in *usercenter.RegisterReq) (*usercenter.RegisterResp, error) {
	// todo: add your logic here and delete this line
	logx.Info("执行rpc方法register.resp")
	// 查询用户名是否存在
	err := l.userDomain.UserExistByName(in.Name)
	if err != nil {
		return nil, err
	}
	// 开始注册用户
	user, err := l.userDomain.Register(in.Name, in.Password, in.Phone, in.OpenId, in.Email, in.Country, in.Gender, in.Activity)
	if err != nil {
		return nil, err
	}
	auth := l.svcCtx.Config.JWTAuth
	access, err := l.ut.GetJwtToken(auth.AccessSecret, time.Now().Unix(), auth.AccessExpire, user.Id, "access")
	if err != nil {
		return nil, err
	}
	refresh, err := l.ut.GetJwtToken(auth.AccessSecret, time.Now().Unix(), auth.RefreshExpire, user.Id, "refresh")
	if err != nil {
		return nil, err
	}
	return &usercenter.RegisterResp{
		Access:  access,
		Refresh: refresh,
	}, nil
}

func (l *UserLogic) Login(in *usercenter.LoginReq) (*usercenter.LoginResp, error) {
	user, err := l.userDomain.Login(in.Name, in.Password)
	if err != nil {
		return nil, err
	}
	auth := l.svcCtx.Config.JWTAuth
	access, err := l.ut.GetJwtToken(auth.AccessSecret, time.Now().Unix(), auth.AccessExpire, user.Id, "access")
	if err != nil {
		return nil, err
	}
	refresh, err := l.ut.GetJwtToken(auth.AccessSecret, time.Now().Unix(), auth.RefreshExpire, user.Id, "refresh")
	if err != nil {
		return nil, err
	}
	return &usercenter.LoginResp{
		Access:  access,
		Refresh: refresh,
	}, nil
}

func (l *UserLogic) UserUpdate(in *usercenter.UserUpdateReq) (*usercenter.UserUpdateResp, error) {
	// 查重
	err := l.userDomain.UserUpdateExist(in.Name, in.Email, in.Phone, in.Id)
	if err != nil {
		return nil, err
	}
	// 修改
	err = l.userDomain.UserUpdate(in.Id, in.Name, in.Phone, in.Email, in.OpenId, in.Country, in.Gender, in.Activity)
	if err != nil {
		return nil, err
	}
	return &usercenter.UserUpdateResp{}, nil
}

func (l *UserLogic) UserAddRole(in *usercenter.UserAddRoleReq) (*usercenter.UserAddRoleResp, error) {
	// 是否已经添加角色, 查询角色是否存在
	err := l.userDomain.UserAddRoleExist(in.UserId, in.RoleId)
	if err != nil {
		return nil, err
	}

	// 添加角色
	err = l.userDomain.UserAddRole(in.UserId, in.RoleId)
	if err != nil {
		return nil, err
	}
	return &usercenter.UserAddRoleResp{}, nil
}

func (l *UserLogic) UserUpdateRole(in *usercenter.UserUpdateRoleReq) (*usercenter.UserUpdateRoleResp, error) {
	// 修改
	err := l.userDomain.UserUpdateRole(in.UserId, in.OldRoleId, in.NewRoleId)
	if err != nil {
		return nil, err
	}
	return &usercenter.UserUpdateRoleResp{}, nil
}

func (l *UserLogic) UserList(in *usercenter.UserListReq) (*usercenter.UserListResp, error) {
	userList, err := l.userDomain.UserList(in.Page)
	if err != nil {
		return nil, err
	}

	var resp []*usercenter.UserBase
	if len(userList) > 0 {
		for _, user := range userList {
			resp = append(resp, &usercenter.UserBase{
				Id:       user.Id,
				Activity: user.Activity,
				Gender:   user.Gender,
				Country:  user.Country,
				Email:    user.Email,
				OpenId:   user.OpenId,
				Phone:    user.Phone,
				Name:     user.Name,
				CreateAt: user.CreateAt.Unix(),
				UpdateAt: user.UpdateAt.Unix(),
			})
		}
	}
	return &usercenter.UserListResp{
		UserList: resp,
	}, nil
}

func (l *UserLogic) UserDetail(in *usercenter.UserDetailReq) (*usercenter.UserDetailResp, error) {
	user, err := l.userDomain.UserDetail(in.Id)
	if err != nil {
		return nil, err
	}

	return &usercenter.UserDetailResp{
		UserInfo: &usercenter.UserBase{
			Id:       user.Id,
			Activity: user.Activity,
			Gender:   user.Gender,
			Country:  user.Country,
			Email:    user.Email,
			OpenId:   user.OpenId,
			Phone:    user.Phone,
			Name:     user.Name,
			CreateAt: user.CreateAt.Unix(),
			UpdateAt: user.UpdateAt.Unix(),
		},
	}, nil
}

func (l *UserLogic) UserGetRole(in *usercenter.UserGetRoleReq) (*usercenter.UserGetRoleResp, error) {
	roleList, err := l.userDomain.UserGetRole(in.Id)
	if err != nil {
		return nil, err
	}
	var resp []*usercenter.RoleBase
	if len(roleList) > 0 {
		mySet := mapset.NewSet[int64]()
		for _, group := range roleList {
			if !mySet.Contains(group.RoleModel.Id) {
				resp = append(resp, &usercenter.RoleBase{
					Id:       group.RoleModel.Id,
					Name:     group.RoleModel.Name,
					ParentId: group.RoleModel.ParentId,
					Weight:   group.RoleModel.Weight,
					CreateAt: group.RoleModel.CreateAt.Unix(),
					UpdateAt: group.RoleModel.UpdateAt.Unix(),
				})
				mySet.Add(group.RoleModel.Id)
			}
		}
	}
	return &usercenter.UserGetRoleResp{
		RoleList: resp,
	}, nil
}

func (l *UserLogic) UserGetPower(in *usercenter.UserGetPowerReq) (*usercenter.UserGetPowerResp, error) {
	powerList, err := l.userDomain.UserGetPower(in.Id)
	if err != nil {
		return nil, err
	}
	var resp []*usercenter.PowerBase
	if len(powerList) > 0 {
		mySet := mapset.NewSet[int64]()
		for _, power := range powerList {
			if !mySet.Contains(power.Id) {
				resp = append(resp, &usercenter.PowerBase{
					Id:       power.Id,
					Name:     power.Name,
					Method:   power.Method,
					Url:      power.Url,
					ParentId: power.ParentId,
					CreateAt: power.CreateAt.Unix(),
					UpdateAt: power.UpdateAt.Unix(),
				})
				mySet.Add(power.Id)
			}
		}
	}
	return &usercenter.UserGetPowerResp{
		PowerList: resp,
	}, nil
}
